package groovy.syntax

/**
 * @author houjinxin
 *	演示各种字符串
 */

//单引字符串     单引字符串是普通java.lang.String对象，不能背篡改
'a single quoted string'

//String concatenation 字符串联结
println 'a' + 'b'

//三单引字符串     三单引字符串是普通java.lang.String对象，不能背篡改
//可以多行，包含格式
def triple_single_quoted_string = '''
	a triple 
	single quoted string
'''
//去掉缩进格式
println triple_single_quoted_string.stripIndent()
println triple_single_quoted_string.stripMargin()

//加上\输出时没有第一行空行
def triple_single_quoted_string_nofirstline = '''\
	a triple\
	single quoted string\
'''
println triple_single_quoted_string_nofirstline.stripIndent()
assert !triple_single_quoted_string_nofirstline.startsWith('\n')

//转义特殊符串 以防止字符串终结
println 'an escaped single quote: \' needs a backslash'

def 转移字符列表 = '''
Escape sequence	Character
'\t',           tabulation
'\b',           backspace
'\n',           newline
'\r',           carriage return
'\f',           formfeed
'\\',           backslash
'\'',           single quote (for single quoted and triple single quoted strings)
'\"',           double quote (for double quoted and triple double quoted strings)
'''
println 转移字符列表

//Unicode escape sequence （Unicode 转码） 以反斜杠 + 'u' + 符号在字符集中的代码
println 'The Euro currency symbol: \u20AC'

//双引号字符串,如果没有嵌入值则为java.lang.String ,如果有则为GString对象。
//注意：只有双引号字符串能
def insertValue = 'a'
println "hahah-${insertValue}"
println 'hahah-${insertValue}'
//println "hhah${fdsfsd}" //这种写法是错误的
println "hhah\${fdsfsd}" //想要输出${}必须要对$进行转义

//${} 中可以使用运算符和表达式 例子如下
def operation = "${ 2 + 3}"
println operation
def nameMap = [name:'houjinxin',age:25]
def expression = "${nameMap.name}"
println expression

//${} 可以省略{} 例如
println "$nameMap.name"

println 3.15.toString()

//假如表达式中含有类似方法调用的小括号，闭包{}或算数运算符将是非法的  例如 以下用法将抛出 groovy.lang.MissingPropertyException
//因为Groovy 会认为是访问number的toString属性，所以会出现没有number没有这个属性的异常

def shouldFail(MissingPropertyException) {
	def number = 3.14
	println "${number.toString()}"
	println "$number.toString()"
	println "${number.toString}()"
}
//shouldFail()

//需要转义在$符号前加\
def othsse = '34424'
println "\${othsse}"
assert '${othsse}' == "\${othsse}"

//闭包表达式  包含一个"->"的表达式为闭包表达式  
def sParameterLessClosure = "1 + 2 == ${-> 3}"  //定义一个无参闭包，返回值为3
assert sParameterLessClosure == '1 + 2 == 3'

def sOneParamClosure = "1 + 2 == ${ w -> w << 3}" //定义一个java.io.StringWriter 将3注入StringWriter中 返回
assert sOneParamClosure == '1 + 2 == 3'

println "${ w -> w << 3}"
//表面上看，定义表达式，并篡改之是一件多余的事，但闭包比起仅仅写表达式有一个很大的优势，就是lazy 计算 。看下面的例子

def number = 1
def eagerGString = "value == ${number}"
def lazyGString = "value == ${-> number }"
assert eagerGString == "value == 1"
assert lazyGString ==  "value == 1"

number = 2 //当number为2时，eagerGString 仍然为1 而 lazyGString 却已经变成了2
assert eagerGString == "value == 1"
assert lazyGString ==  "value == 2"

//与java相交互的能力
String takeString(String message) {
	assert message instanceof String //转为String
	return message
}

def message = "The message is ${'hello'}"
assert message instanceof GString //GString

def result = takeString(message)
println result
assert result instanceof String
assert result == 'The message is hello'

//GString 与 String 的 hashCode方法
def var = 'b'
def gString = "one: ${var}"
def string = "one: b"
assert gString.hashCode() != string.hashCode()
//可见GString的HashCode和String的HashCode是不同的，所以不能以GString作为Map的Key值
def key = "a"
def m = ["${key}": "letter ${key}"]

assert m["a"] == null

//三个双引号
def name = 'Groovy'
def template = """
    Dear Mr ${name},

    You're the winner of the lottery!

    Yours sincerly,

    Dave
"""
assert template.toString().contains('Groovy')

//Slashy string 斜线字符串,常用于正则表达式
def fooPattern = /.*foo.*/
assert fooPattern == '.*foo.*'

//需要对斜杠'/'进行转义
def escapeSlash = /The character \/ is a forward slash/
assert escapeSlash == 'The character / is a forward slash'
//这种字符串 可以是多行的
def multilineSlashy = /one
two
three/
assert multilineSlashy.contains('\n')
//也可以用GString来修改
def color = 'blue'
def interpolatedSlashy = /a ${color} car/
assert interpolatedSlashy == 'a blue car'
//还有一些需要注意的，如下 空斜线字符串// 它被编译器认为是注释 并不等于 ''
//assert '' == //

// $/字符串
def name1 = "Guillaume"
def date = "April, 1st"

def dollarSlashy = $/
	Hello $name1,
	today we're ${date}.

	$ dollar sign
	$$ escaped dollar sign
	\ backslash
	/ forward slash
	$/ escaped forward slash
	$/$ escaped dollar slashy string delimiter
/$
assert [
	'Guillaume',
	'April, 1st',
	'$ dollar sign',
	'$ escaped dollar sign',
	'\\ backslash',
	'/ forward slash',
	'$/ escaped forward slash',
	'/$ escaped dollar slashy string delimiter'
].each { dollarSlashy.contains(it) }
		
//字符 groovy不像java 其中没有特别明确的指定一个groovy String 实际上为Character，如果要显示指定为Character 有如下三种方式
char c1 = 'A' //指定char类型
assert c1 instanceof Character

def c2 = 'B' as char //as char as操作符
assert c2 instanceof Character

def c3 = (char)'C' //强制转换
assert c3 instanceof Character
